/**
 * 
 */
package com.gr.staffpm.pages.projects;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.wicketstuff.annotation.mount.MountPath;
import org.wicketstuff.annotation.strategy.MountHybrid;

import com.gr.staffpm.StaffPMWebPage;
import com.gr.staffpm.datatypes.Project;
import com.gr.staffpm.datatypes.Role;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.form.validation.ProjectKeyValidator;
import com.gr.staffpm.model.StringModel;
import com.gr.staffpm.pages.behaviour.FocusOnLoadBehavior;
import com.gr.staffpm.pages.error.UnauthorizedPage;
import com.gr.staffpm.projects.model.ProjectPermission;
import com.gr.staffpm.projects.service.ProjectService;
import com.gr.staffpm.security.constants.CRUDProjectPermission;
import com.gr.staffpm.security.service.UserService;
import com.gr.staffpm.widget.jqgrid.EditableGrid;
import com.gr.staffpm.widget.jqgrid.column.AbstractEditablePropertyColumn;
import com.gr.staffpm.widget.jqgrid.column.EditableCellPanel;
import com.gr.staffpm.widget.jqgrid.column.EditableDropDownCellPanel;


/**
 * @author Graham Rhodes 10 Apr 2011 23:54:40
 */
@MountHybrid
@MountPath(path = "secure/AddProject")
public class AddProjectPage extends StaffPMWebPage {

    @SpringBean(name = "projectService")
    private ProjectService projectService;
    @SpringBean(name = "userService")
    private UserService userService;
    private final Project newProject = new Project();
    private final TextField<String> projectName = new TextField<String>("projectName", new StringModel(""));
    private final TextField<String> key = new TextField<String>("key", new StringModel(""));
    private final TextArea<String> description = new TextArea<String>("description", new StringModel(""));
    private final List<ProjectPermission> permissions = new ArrayList<ProjectPermission>();

    public AddProjectPage() {
        if (SecurityUtils.getSubject().isPermitted("project:create")) {
            Form<Project> form = new Form<Project>("addProjectForm") {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onSubmit() {
                    AddProjectPage.this.onSubmit();
                }
            };
            add(form);

            add(new FeedbackPanel("feedback"));

            projectName.setRequired(true);
            projectName.add(new FocusOnLoadBehavior());
            form.add(projectName);

            key.add(new ProjectKeyValidator(5));
            key.setRequired(true);
            form.add(key);

            form.add(new EditableGrid<ProjectPermission>("grid", getColumns(), new ArrayList<ProjectPermission>(), new ProjectPermission()) {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onSave(ProjectPermission pp, AjaxRequestTarget target) {
                    if (permissions.contains(pp)) {
                        permissions.remove(pp);
                    }
                    permissions.add(pp);
                }

                @Override
                protected void onDelete(ProjectPermission pp, AjaxRequestTarget target) {
                    permissions.remove(pp);
                }

            });

            form.add(description);

            Button cancel = new Button("cancelButton") {

                private static final long serialVersionUID = 1L;

                @Override
                public void onSubmit() {
                    setResponsePage(Projects.class);
                }

            };
            cancel.setDefaultFormProcessing(false);
            form.add(cancel);
        } else
            setResponsePage(UnauthorizedPage.class);
    }

    private List<AbstractEditablePropertyColumn<ProjectPermission>> getColumns() {
        List<AbstractEditablePropertyColumn<ProjectPermission>> columns = new ArrayList<AbstractEditablePropertyColumn<ProjectPermission>>();
        columns.add(new AbstractEditablePropertyColumn<ProjectPermission>(new Model<String>("Role"), "role") {

            private static final long serialVersionUID = 1L;

            @Override
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public EditableCellPanel getEditableCellPanel(String componentId) {
                return new EditableDropDownCellPanel(componentId, this, userService.getAllRoles(), new ChoiceRenderer<Role>("role", "roleId"));
            }

        });
        columns.add(new AbstractEditablePropertyColumn<ProjectPermission>(new Model<String>("Permission"), "permission") {

            private static final long serialVersionUID = 1L;

            @Override
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public EditableCellPanel getEditableCellPanel(String componentId) {
                return new EditableDropDownCellPanel(componentId, this, CRUDProjectPermission.valuesAsList(), new ChoiceRenderer<CRUDProjectPermission>("name", "ordinal"));
            }

        });
        return columns;
    }

    protected void onSubmit() {
        if (SecurityUtils.getSubject().isPermitted("project:create")) {
            User currUser = userService.getCurrentUser();

            newProject.setStartDate(new Date());
            newProject.setProjectName(projectName.getValue());
            newProject.setOwner(currUser);
            newProject.setKey(key.getValue());
            newProject.setDescription(description.getValue());
            newProject.setCreated(new Date());
            newProject.setCreatedBy(currUser);
            newProject.setLastUpdated(new Date());
            newProject.setUpdatedBy(currUser);

            if (!projectService.checkProjectExists(newProject)) {
                projectService.addProject(newProject);
                for (ProjectPermission pp : permissions) {
                    userService.createPermission(pp.getRole(), pp.getPermission(), newProject);
                }
            } else
                error("A project already exists with that key.");
        }
        //Send user back to previous page
        setResponsePage(Projects.class);
    }

    /* (non-Javadoc)
     * @see com.gr.staffpm.StaffPMWebPage#getTitle()
     */
    @Override
    public String getTitle() {
        return "Add Project - StaffPM";
    }

}
